package jsr166.contrib.uncontended;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;

/**
 * This lock class is designed to be used in situations where you believe no
 * synchronization is needed, but you want to verify that at runtime.
 * 
 * If one thread tries to acquire a lock while another thread already holds
 * the lock, the attempt to acquire the lock will thrown an 
 * UnexpectedConcurrentAccessException, as will all future unlock or lock
 * operations on that lock.
 * 
 * If you create a Condition from this lock, you can signal it but an attempt
 * to await on it will throw an UnsupportedOperationException.
 *
 */
public class UncontendedLock extends AbstractOwnedUncontendedLock {

    public static Lock getOptionalInstance() {
        if (AbstractUncontendedLock.ENFORCE_UNCONTENDED_LOCKS) return new UncontendedLock();
        return new NoOpUncontendedLock();
    }
    AtomicReference<Thread> threadHoldingLock = new AtomicReference<Thread>();
    int lockCount = 0;

    public void lock() {
        setOwningThread(threadHoldingLock);
        lockCount++;
    }

    public void unlock() {
        if (broken) lockWasContended();
        lockCount--;
        if (lockCount == 0)
            threadHoldingLock.set(null);
    }

}
